home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / python2.4 / sgmllib.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2005-10-18  |  14KB  |  561 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.4)
  3.  
  4. '''A parser for SGML, using the derived class as a static DTD.'''
  5. import markupbase
  6. import re
  7. __all__ = [
  8.     'SGMLParser',
  9.     'SGMLParseError']
  10. interesting = re.compile('[&<]')
  11. incomplete = re.compile('&([a-zA-Z][a-zA-Z0-9]*|#[0-9]*)?|<([a-zA-Z][^<>]*|/([a-zA-Z][^<>]*)?|![^<>]*)?')
  12. entityref = re.compile('&([a-zA-Z][-.a-zA-Z0-9]*)[^a-zA-Z0-9]')
  13. charref = re.compile('&#([0-9]+)[^0-9]')
  14. starttagopen = re.compile('<[>a-zA-Z]')
  15. shorttagopen = re.compile('<[a-zA-Z][-.a-zA-Z0-9]*/')
  16. shorttag = re.compile('<([a-zA-Z][-.a-zA-Z0-9]*)/([^/]*)/')
  17. piclose = re.compile('>')
  18. endbracket = re.compile('[<>]')
  19. tagfind = re.compile('[a-zA-Z][-_.a-zA-Z0-9]*')
  20. attrfind = re.compile('\\s*([a-zA-Z_][-:.a-zA-Z_0-9]*)(\\s*=\\s*(\\\'[^\\\']*\\\'|"[^"]*"|[-a-zA-Z0-9./,:;+*%?!&$\\(\\)_#=~\\\'"@]*))?')
  21.  
  22. class SGMLParseError(RuntimeError):
  23.     '''Exception raised for all parse errors.'''
  24.     pass
  25.  
  26.  
  27. class SGMLParser(markupbase.ParserBase):
  28.     
  29.     def __init__(self, verbose = 0):
  30.         '''Initialize and reset this instance.'''
  31.         self.verbose = verbose
  32.         self.reset()
  33.  
  34.     
  35.     def reset(self):
  36.         '''Reset this instance. Loses all unprocessed data.'''
  37.         self._SGMLParser__starttag_text = None
  38.         self.rawdata = ''
  39.         self.stack = []
  40.         self.lasttag = '???'
  41.         self.nomoretags = 0
  42.         self.literal = 0
  43.         markupbase.ParserBase.reset(self)
  44.  
  45.     
  46.     def setnomoretags(self):
  47.         '''Enter literal mode (CDATA) till EOF.
  48.  
  49.         Intended for derived classes only.
  50.         '''
  51.         self.nomoretags = self.literal = 1
  52.  
  53.     
  54.     def setliteral(self, *args):
  55.         '''Enter literal mode (CDATA).
  56.  
  57.         Intended for derived classes only.
  58.         '''
  59.         self.literal = 1
  60.  
  61.     
  62.     def feed(self, data):
  63.         """Feed some data to the parser.
  64.  
  65.         Call this as often as you want, with as little or as much text
  66.         as you want (may include '
  67. ').  (This just saves the text,
  68.         all the processing is done by goahead().)
  69.         """
  70.         self.rawdata = self.rawdata + data
  71.         self.goahead(0)
  72.  
  73.     
  74.     def close(self):
  75.         '''Handle the remaining data.'''
  76.         self.goahead(1)
  77.  
  78.     
  79.     def error(self, message):
  80.         raise SGMLParseError(message)
  81.  
  82.     
  83.     def goahead(self, end):
  84.         rawdata = self.rawdata
  85.         i = 0
  86.         n = len(rawdata)
  87.         while i < n:
  88.             if self.nomoretags:
  89.                 self.handle_data(rawdata[i:n])
  90.                 i = n
  91.                 break
  92.             
  93.             match = interesting.search(rawdata, i)
  94.             if match:
  95.                 j = match.start()
  96.             else:
  97.                 j = n
  98.             if i < j:
  99.                 self.handle_data(rawdata[i:j])
  100.             
  101.             i = j
  102.             if i == n:
  103.                 break
  104.             
  105.             if rawdata[i] == '<':
  106.                 if starttagopen.match(rawdata, i):
  107.                     if self.literal:
  108.                         self.handle_data(rawdata[i])
  109.                         i = i + 1
  110.                         continue
  111.                     
  112.                     k = self.parse_starttag(i)
  113.                     if k < 0:
  114.                         break
  115.                     
  116.                     i = k
  117.                     continue
  118.                 
  119.                 if rawdata.startswith('</', i):
  120.                     k = self.parse_endtag(i)
  121.                     if k < 0:
  122.                         break
  123.                     
  124.                     i = k
  125.                     self.literal = 0
  126.                     continue
  127.                 
  128.                 if self.literal:
  129.                     if n > i + 1:
  130.                         self.handle_data('<')
  131.                         i = i + 1
  132.                         continue
  133.                     break
  134.                     continue
  135.                 
  136.                 if rawdata.startswith('<!--', i):
  137.                     k = self.parse_comment(i)
  138.                     if k < 0:
  139.                         break
  140.                     
  141.                     i = k
  142.                     continue
  143.                 
  144.                 if rawdata.startswith('<?', i):
  145.                     k = self.parse_pi(i)
  146.                     if k < 0:
  147.                         break
  148.                     
  149.                     i = i + k
  150.                     continue
  151.                 
  152.                 if rawdata.startswith('<!', i):
  153.                     k = self.parse_declaration(i)
  154.                     if k < 0:
  155.                         break
  156.                     
  157.                     i = k
  158.                     continue
  159.                 
  160.             elif rawdata[i] == '&':
  161.                 if self.literal:
  162.                     self.handle_data(rawdata[i])
  163.                     i = i + 1
  164.                     continue
  165.                 
  166.                 match = charref.match(rawdata, i)
  167.                 if match:
  168.                     name = match.group(1)
  169.                     self.handle_charref(name)
  170.                     i = match.end(0)
  171.                     if rawdata[i - 1] != ';':
  172.                         i = i - 1
  173.                         continue
  174.                     continue
  175.                 
  176.                 match = entityref.match(rawdata, i)
  177.                 if match:
  178.                     name = match.group(1)
  179.                     self.handle_entityref(name)
  180.                     i = match.end(0)
  181.                     if rawdata[i - 1] != ';':
  182.                         i = i - 1
  183.                         continue
  184.                     continue
  185.                 
  186.             else:
  187.                 self.error('neither < nor & ??')
  188.             match = incomplete.match(rawdata, i)
  189.             if not match:
  190.                 self.handle_data(rawdata[i])
  191.                 i = i + 1
  192.                 continue
  193.             
  194.             j = match.end(0)
  195.             if j == n:
  196.                 break
  197.             
  198.             self.handle_data(rawdata[i:j])
  199.             i = j
  200.         if end and i < n:
  201.             self.handle_data(rawdata[i:n])
  202.             i = n
  203.         
  204.         self.rawdata = rawdata[i:]
  205.  
  206.     _decl_otherchars = '='
  207.     
  208.     def parse_pi(self, i):
  209.         rawdata = self.rawdata
  210.         if rawdata[i:i + 2] != '<?':
  211.             self.error('unexpected call to parse_pi()')
  212.         
  213.         match = piclose.search(rawdata, i + 2)
  214.         if not match:
  215.             return -1
  216.         
  217.         j = match.start(0)
  218.         self.handle_pi(rawdata[i + 2:j])
  219.         j = match.end(0)
  220.         return j - i
  221.  
  222.     
  223.     def get_starttag_text(self):
  224.         return self._SGMLParser__starttag_text
  225.  
  226.     
  227.     def parse_starttag(self, i):
  228.         self._SGMLParser__starttag_text = None
  229.         start_pos = i
  230.         rawdata = self.rawdata
  231.         if shorttagopen.match(rawdata, i):
  232.             match = shorttag.match(rawdata, i)
  233.             if not match:
  234.                 return -1
  235.             
  236.             (tag, data) = match.group(1, 2)
  237.             self._SGMLParser__starttag_text = '<%s/' % tag
  238.             tag = tag.lower()
  239.             k = match.end(0)
  240.             self.finish_shorttag(tag, data)
  241.             self._SGMLParser__starttag_text = rawdata[start_pos:match.end(1) + 1]
  242.             return k
  243.         
  244.         match = endbracket.search(rawdata, i + 1)
  245.         if not match:
  246.             return -1
  247.         
  248.         j = match.start(0)
  249.         attrs = []
  250.         if rawdata[i:i + 2] == '<>':
  251.             k = j
  252.             tag = self.lasttag
  253.         else:
  254.             match = tagfind.match(rawdata, i + 1)
  255.             if not match:
  256.                 self.error('unexpected call to parse_starttag')
  257.             
  258.             k = match.end(0)
  259.             tag = rawdata[i + 1:k].lower()
  260.             self.lasttag = tag
  261.         while k < j:
  262.             match = attrfind.match(rawdata, k)
  263.             if not match:
  264.                 break
  265.             
  266.             (attrname, rest, attrvalue) = match.group(1, 2, 3)
  267.             if not rest:
  268.                 attrvalue = attrname
  269.             elif "'" == "'":
  270.                 pass
  271.             elif not "'" == attrvalue[-1:]:
  272.                 if '"' == '"':
  273.                     pass
  274.                 elif '"' == attrvalue[-1:]:
  275.                     attrvalue = attrvalue[1:-1]
  276.                 
  277.             attrs.append((attrname.lower(), attrvalue))
  278.             k = match.end(0)
  279.             continue
  280.             attrvalue[:1]
  281.         if rawdata[j] == '>':
  282.             j = j + 1
  283.         
  284.         self._SGMLParser__starttag_text = rawdata[start_pos:j]
  285.         self.finish_starttag(tag, attrs)
  286.         return j
  287.  
  288.     
  289.     def parse_endtag(self, i):
  290.         rawdata = self.rawdata
  291.         match = endbracket.search(rawdata, i + 1)
  292.         if not match:
  293.             return -1
  294.         
  295.         j = match.start(0)
  296.         tag = rawdata[i + 2:j].strip().lower()
  297.         if rawdata[j] == '>':
  298.             j = j + 1
  299.         
  300.         self.finish_endtag(tag)
  301.         return j
  302.  
  303.     
  304.     def finish_shorttag(self, tag, data):
  305.         self.finish_starttag(tag, [])
  306.         self.handle_data(data)
  307.         self.finish_endtag(tag)
  308.  
  309.     
  310.     def finish_starttag(self, tag, attrs):
  311.         
  312.         try:
  313.             method = getattr(self, 'start_' + tag)
  314.         except AttributeError:
  315.             
  316.             try:
  317.                 method = getattr(self, 'do_' + tag)
  318.             except AttributeError:
  319.                 self.unknown_starttag(tag, attrs)
  320.                 return -1
  321.  
  322.             self.handle_starttag(tag, method, attrs)
  323.             return 0
  324.  
  325.         self.stack.append(tag)
  326.         self.handle_starttag(tag, method, attrs)
  327.         return 1
  328.  
  329.     
  330.     def finish_endtag(self, tag):
  331.         if not tag:
  332.             found = len(self.stack) - 1
  333.             if found < 0:
  334.                 self.unknown_endtag(tag)
  335.                 return None
  336.             
  337.         elif tag not in self.stack:
  338.             
  339.             try:
  340.                 method = getattr(self, 'end_' + tag)
  341.             except AttributeError:
  342.                 self.unknown_endtag(tag)
  343.  
  344.             self.report_unbalanced(tag)
  345.             return None
  346.         
  347.         found = len(self.stack)
  348.         for i in range(found):
  349.             if self.stack[i] == tag:
  350.                 found = i
  351.                 continue
  352.         
  353.         while len(self.stack) > found:
  354.             tag = self.stack[-1]
  355.             
  356.             try:
  357.                 method = getattr(self, 'end_' + tag)
  358.             except AttributeError:
  359.                 method = None
  360.  
  361.             if method:
  362.                 self.handle_endtag(tag, method)
  363.             else:
  364.                 self.unknown_endtag(tag)
  365.             del self.stack[-1]
  366.  
  367.     
  368.     def handle_starttag(self, tag, method, attrs):
  369.         method(attrs)
  370.  
  371.     
  372.     def handle_endtag(self, tag, method):
  373.         method()
  374.  
  375.     
  376.     def report_unbalanced(self, tag):
  377.         if self.verbose:
  378.             print '*** Unbalanced </' + tag + '>'
  379.             print '*** Stack:', self.stack
  380.         
  381.  
  382.     
  383.     def handle_charref(self, name):
  384.         '''Handle character reference, no need to override.'''
  385.         
  386.         try:
  387.             n = int(name)
  388.         except ValueError:
  389.             self.unknown_charref(name)
  390.             return None
  391.  
  392.         if n <= n:
  393.             pass
  394.         elif not n <= 255:
  395.             self.unknown_charref(name)
  396.             return None
  397.         
  398.         self.handle_data(chr(n))
  399.  
  400.     entitydefs = {
  401.         'lt': '<',
  402.         'gt': '>',
  403.         'amp': '&',
  404.         'quot': '"',
  405.         'apos': "'" }
  406.     
  407.     def handle_entityref(self, name):
  408.         '''Handle entity references.
  409.  
  410.         There should be no need to override this method; it can be
  411.         tailored by setting up the self.entitydefs mapping appropriately.
  412.         '''
  413.         table = self.entitydefs
  414.         if name in table:
  415.             self.handle_data(table[name])
  416.         else:
  417.             self.unknown_entityref(name)
  418.             return None
  419.  
  420.     
  421.     def handle_data(self, data):
  422.         pass
  423.  
  424.     
  425.     def handle_comment(self, data):
  426.         pass
  427.  
  428.     
  429.     def handle_decl(self, decl):
  430.         pass
  431.  
  432.     
  433.     def handle_pi(self, data):
  434.         pass
  435.  
  436.     
  437.     def unknown_starttag(self, tag, attrs):
  438.         pass
  439.  
  440.     
  441.     def unknown_endtag(self, tag):
  442.         pass
  443.  
  444.     
  445.     def unknown_charref(self, ref):
  446.         pass
  447.  
  448.     
  449.     def unknown_entityref(self, ref):
  450.         pass
  451.  
  452.  
  453.  
  454. class TestSGMLParser(SGMLParser):
  455.     
  456.     def __init__(self, verbose = 0):
  457.         self.testdata = ''
  458.         SGMLParser.__init__(self, verbose)
  459.  
  460.     
  461.     def handle_data(self, data):
  462.         self.testdata = self.testdata + data
  463.         if len(repr(self.testdata)) >= 70:
  464.             self.flush()
  465.         
  466.  
  467.     
  468.     def flush(self):
  469.         data = self.testdata
  470.         if data:
  471.             self.testdata = ''
  472.             print 'data:', repr(data)
  473.         
  474.  
  475.     
  476.     def handle_comment(self, data):
  477.         self.flush()
  478.         r = repr(data)
  479.         if len(r) > 68:
  480.             r = r[:32] + '...' + r[-32:]
  481.         
  482.         print 'comment:', r
  483.  
  484.     
  485.     def unknown_starttag(self, tag, attrs):
  486.         self.flush()
  487.         if not attrs:
  488.             print 'start tag: <' + tag + '>'
  489.         else:
  490.             print 'start tag: <' + tag,
  491.             for name, value in attrs:
  492.                 print name + '=' + '"' + value + '"',
  493.             
  494.             print '>'
  495.  
  496.     
  497.     def unknown_endtag(self, tag):
  498.         self.flush()
  499.         print 'end tag: </' + tag + '>'
  500.  
  501.     
  502.     def unknown_entityref(self, ref):
  503.         self.flush()
  504.         print '*** unknown entity ref: &' + ref + ';'
  505.  
  506.     
  507.     def unknown_charref(self, ref):
  508.         self.flush()
  509.         print '*** unknown char ref: &#' + ref + ';'
  510.  
  511.     
  512.     def unknown_decl(self, data):
  513.         self.flush()
  514.         print '*** unknown decl: [' + data + ']'
  515.  
  516.     
  517.     def close(self):
  518.         SGMLParser.close(self)
  519.         self.flush()
  520.  
  521.  
  522.  
  523. def test(args = None):
  524.     import sys as sys
  525.     if args is None:
  526.         args = sys.argv[1:]
  527.     
  528.     if args and args[0] == '-s':
  529.         args = args[1:]
  530.         klass = SGMLParser
  531.     else:
  532.         klass = TestSGMLParser
  533.     if args:
  534.         file = args[0]
  535.     else:
  536.         file = 'test.html'
  537.     if file == '-':
  538.         f = sys.stdin
  539.     else:
  540.         
  541.         try:
  542.             f = open(file, 'r')
  543.         except IOError:
  544.             msg = None
  545.             print file, ':', msg
  546.             sys.exit(1)
  547.  
  548.     data = f.read()
  549.     if f is not sys.stdin:
  550.         f.close()
  551.     
  552.     x = klass()
  553.     for c in data:
  554.         x.feed(c)
  555.     
  556.     x.close()
  557.  
  558. if __name__ == '__main__':
  559.     test()
  560.  
  561.